Current Sprint: 1. 完成 HappyPath: 可以建立一場遊戲,玩到結束
repo: https://github.com/side-project-at-SPT/ithome-ironman-2024-san-juan
swagger docs: https://side-project-at-spt.github.io/ithome-ironman-2024-san-juan/
昨天開了 GET /api/v1/games 取得所有遊戲
今天把後面做完

因為目前沒有資料
rails rswag
 
我們只需要回傳 id, status
Gemfile 將 jbuilder 註解取消app/views/api/v1/games/create.json.jbuilder
json.id @game.id
json.status @game.status

index.json.jubilder
json.games @games do |game|
  json.partial! "api/v1/games/game", game: game
end
_game.json.jbuilder
json.id game.id
json.status game.status
create.json.jbuilder
json.partial! "api/v1/games/game", game: @game
games_controller.rb
class Api::V1::GamesController < ApplicationController
  def index
    @games = Game.all
  end
  def create
    @game = Game.new(status: "playing")
    unless @game.save
      render json: { error: @game.errors.full_messages }
    end
  end
end


收工
class Api::V1::GamesController < ApplicationController
# ...
    
  def play
    @game = Game.find(params[:id])
    @game.play
    return render status: :unprocessable_entity, json: { error: @game.errors.full_messages } if @game.errors.any?
    @message = "你選擇了礦工"
  end
# ...
end
Rails.application.routes.draw do
# ...
    
  namespace :api do
    namespace :v1 do
      resources :games, only: [ :index, :create ] do
        member do
          post :play
        end
      end
    end
  end
    
# ...
end
require 'swagger_helper'
RSpec.describe "Api::V1::Games", type: :request do
  path '/api/v1/games' do
    get 'List all games' do
      tags 'Games'
      produces 'application/json'
      before do
        Game.create
        Game.create(status: 'playing')
      end
      response '200', 'Games found' do
        schema type: :object,
          properties: {
            games: {
              type: :array,
              items: {
                type: :object,
                properties: {
                  id: { type: :integer },
                  status: { type: :string }
                },
                required: [ 'id', 'status' ]
              }
            }
          },
          required: [ 'games' ]
        run_test! do
          json = JSON.parse(response.body)
          expect(json['games'].size).to eq(2)
          expect(json['games'].any? { |game| game['status'] == 'unknown' }).to be_truthy
          expect(json['games'].any? { |game| game['status'] == 'playing' }).to be_truthy
        end
      end
    end
    post 'Create a game' do
      tags 'Games'
      consumes 'application/json'
      produces 'application/json'
      response '200', 'Game created' do
        schema type: :object,
          properties: {
            id: { type: :integer },
            status: { type: :string }
          },
          required: [ 'id', 'status' ]
        run_test! do
          json = JSON.parse(response.body)
          expect(json['status']).to eq('playing')
        end
      end
    end
  end
  path '/api/v1/games/{id}/play' do
    post 'Play a game' do
      tags 'Games'
      consumes 'application/json'
      produces 'application/json'
      let(:game) { Game.create(status: 'playing') }
      parameter name: :id, in: :path, type: :integer, required: true
      parameter name: :game, in: :body, schema: {
        type: :object,
        properties: {
          choice: { type: :string }
        },
        required: [ 'choice' ]
      }
      response '200', 'Game played' do
        schema type: :object,
        properties: {
          id: { type: :integer },
          status: { type: :string },
          message: { type: :string }
        },
        required: [ 'id', 'status', 'message' ]
        let(:id) { game.id }
        run_test! do
          json = JSON.parse(response.body)
          expect(json['status']).to eq('finished')
          expect(json['message']).to eq('你選擇了礦工')
        end
      end
    end
  end
end
models/game.rb 增加 play
class Game < ApplicationRecord
# ...
    
  def play
    return errors.add(:status, "can't be blank") unless status_playing?
    self.status_finished!
  end
    
# ...
end
建立遊戲
查看
行動(選擇礦工)
再次查看
收工
明天做個中場休息
以上不代表明天會做,如有雷同純屬巧合
SPT (Side Project Taiwan) 的宗旨是藉由Side Project開發來成就自我,透過持續學習和合作,共同推動技術和專業的發展。我們相信每一個參與者,無論是什麼專業,都能在這個社群中找到屬於自己的成長空間。
歡迎所有對Side Project開發有興趣的人加入我們,可以是有點子來找夥伴,也可以是來尋找有興趣的Side Project加入,邀請大家一同打造一個充滿活力且有意義的技術社群!
Discord頻道連結:https://sideproj.tw/dc